home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume8 / phoon < prev    next >
Encoding:
Internet Message Format  |  1987-02-26  |  54.0 KB

  1. Subject:  v08i081:  Phase of the moon, date routines
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: Jef Poskanzer <unisoft!charming>
  6. Mod.sources: Volume 8, Issue 81
  7. Archive-name: phoon
  8.  
  9. #! /bin/sh
  10. # This is a shell archive, meaning:
  11. # 1. Remove everything above the #! /bin/sh line.
  12. # 2. Save the resulting text in a file.
  13. # 3. Execute the file with /bin/sh (not csh) to create the files:
  14. #    README Makefile deltime.c deltime.man dtime.c dtimep.lex lexedit.sed
  15. #    lexstring.c libtws.man parsetime.c phoon.c phoon.man tws.h
  16. # This archive created by
  17. # Jef Poskanzer (Paratheo-Anametamystikhood Of Eris Esoteric, Ada Lovelace Cabal)
  18. export PATH; PATH=/bin:$PATH
  19. echo shar: extracting "'README'" '(2571 characters)'
  20. if test -f 'README'
  21. then
  22.     echo shar: will not over-write existing file "'README'"
  23. else
  24. sed 's/^X//' << \SHAR_EOF > 'README'
  25. XSecond distribution of phoon, deltime, and libtws - 24feb87.
  26. X
  27. X
  28. XThis package contains two programs and a library:
  29. X
  30. X    phoon - program to display the PHase of the mOON.  Unlike other
  31. X    such programs, which just tell you how long since first quarter
  32. X    or something like that, phoon *shows* you the phase with a little
  33. X    picture.  I've put an example at the end of this file.  I first
  34. X    wrote this program in Pascal / TOPS-20 at CMU in 1979; I translated
  35. X    it to Ratfor / Software Tools in 1981; and now it's in C / Unix*.
  36. X
  37. X    deltime - program to subtract date/times.  Tells you the difference
  38. X    between two date/times, or between now and a specified date/time.
  39. X    I once used this to help a friend quit smoking - every time she
  40. X    logged in, the computer told her how many days since her last
  41. X    cigarette.  I also use it in my .login, to tell me how old I am.
  42. X
  43. X    libtws - date/time library.  Unlike the standard Unix*
  44. X    date/time routines, libtws lets you parse a date/time string
  45. X    into internal form.  Most of this library came from version
  46. X    6.5 of the MH message handling system, courtesy of Marshall Rose.
  47. X    I extended it somewhat and added the manual entry.
  48. X
  49. X
  50. XFiles in this distribution:
  51. X
  52. X    README        this
  53. X    Makefile        guess
  54. X    deltime.c        source for time subtraction tool
  55. X    deltime.man        manual for time subtraction tool
  56. X    dtime.c        source for most of the time routines
  57. X    dtimep.lex        source for time-parsing routine
  58. X    lexedit.sed        script to modify output of lex
  59. X    lexstring.c        front end for time-parsing routine
  60. X    libtws.man        manual for time library
  61. X    parsetime.c        source for test program
  62. X    phoon.c        source for phase of moon program
  63. X    phoon.man        manual for phase of moon program
  64. X    tws.h        include file for time library
  65. X
  66. X
  67. XUnpack the files, edit Makefile and change the options to suit,
  68. Xmake, and enjoy!  I've tested this stuff under 4.2 BSD, 4.3 BSD,
  69. Xand System V rel 2.  Nevertheless, I'm sure bugs remain.  Feedback
  70. Xis welcome - send bug reports, enhancements, checks, money orders,
  71. Xetc. to the addresses below.
  72. X
  73. X
  74. X     Jef Poskanzer, UniSoft Systems, Berkeley
  75. X     unisoft!jef@ucbvax.Berkeley.Edu
  76. X          ...ucbvax!unisoft!jef
  77. X          (415)644-1230
  78. X
  79. X
  80. X* Unix is a virus from outer space.
  81. X
  82. X
  83. X                 .--
  84. X             .--
  85. X          .-' 
  86. X       .-'@ 
  87. X      /@@@ 
  88. X    ./    
  89. X   /@@  o
  90. X  /@@@@  
  91. X  |@@@@@
  92. X /@@@@@         Last Quarter + 
  93. X | @@@@         4  1:36:10
  94. X |@ @@@        New Moon -     
  95. X |              3  7:34:53
  96. X \  . @ 
  97. X  |     
  98. X  \     @
  99. X   \  o  
  100. X    `\    
  101. X      \    
  102. X       `-.  
  103. X          `-. 
  104. X             `--
  105. X                 `--
  106. SHAR_EOF
  107. if test 2571 -ne "`wc -c < 'README'`"
  108. then
  109.     echo shar: error transmitting "'README'" '(should have been 2571 characters)'
  110. fi
  111. fi # end of overwriting check
  112. echo shar: extracting "'Makefile'" '(2137 characters)'
  113. if test -f 'Makefile'
  114. then
  115.     echo shar: will not over-write existing file "'Makefile'"
  116. else
  117. sed 's/^X//' << \SHAR_EOF > 'Makefile'
  118. X# Makefile for phoon, deltime, parsetime, and libtws (stolen from mh).
  119. X
  120. X
  121. X# Valid options:
  122. X#   BSD42      Set this if your system is BSD 4.2 or later.
  123. X#   SYS5       Set this if your system is System V.
  124. X#   EUROPE     Makes nn/nn/nn mean dd/mm/yy instead of mm/dd/yy.
  125. X#   ATZ        This has something to do with alpha-numeric time zones.
  126. X#   DSTXXX     This has something to do with daylight savings time.
  127. X#   HUJI       I don't
  128. X#   INETONLY           know what
  129. X#   LEXDEBUG                     the rest of these
  130. X#   ONECASE                                        do.
  131. XOPTIONS    =    -DBSD42 -DATZ -DDSTXXX -DONECASE
  132. X
  133. X
  134. XCC      =    cc
  135. XCFLAGS  =    -O $(OPTIONS)
  136. XLDFLAGS =    -ns
  137. X
  138. X.SUFFIXES:    .man .cat
  139. X.man.cat:
  140. X        nroff -h -man $< > $@
  141. X
  142. X
  143. Xall:        phoon phoon.cat deltime deltime.cat libtws.cat
  144. X
  145. X
  146. Xphoon:        phoon.o libtws.a
  147. X        $(CC) $(LDFLAGS) -o phoon phoon.o -lm libtws.a
  148. X
  149. Xphoon.o:    phoon.c tws.h
  150. X
  151. X
  152. Xdeltime:    deltime.o libtws.a
  153. X        $(CC) $(LDFLAGS) -o deltime deltime.o libtws.a
  154. X
  155. Xdeltime.o:    deltime.c tws.h
  156. X
  157. X
  158. Xparsetime:    parsetime.o libtws.a
  159. X        $(CC) $(LDFLAGS) -o parsetime parsetime.o libtws.a
  160. X
  161. Xparsetime.o:    parsetime.c tws.h
  162. X
  163. X
  164. Xlibtws.a:    dtime.o dtimep.o lexstring.o
  165. X        ar r libtws.a dtime.o dtimep.o lexstring.o
  166. X# The following amusing bullshit makes sure that ranlib
  167. X# gets executed if it is present, no matter which shell
  168. X# make uses.  If there's a better way to do this, someone
  169. X# please tell me!
  170. X        -if test -r /usr/bin/ranlib ; then ranlib libtws.a ; fi
  171. X        -if ( -r /usr/bin/ranlib ) ranlib libtws.a
  172. X
  173. X
  174. Xdtime.o:    dtime.c tws.h
  175. X
  176. X
  177. Xdtimep.o:    dtimep.c tws.h
  178. X
  179. Xdtimep.c:    dtimep.lex
  180. X        lex -nt dtimep.lex | sed -f lexedit.sed > dtimep.c
  181. X
  182. X
  183. Xlexstring.o:    lexstring.c
  184. X        $(CC) $(CFLAGS) -c lexstring.c
  185. X
  186. X
  187. Xclean:
  188. X        -rm -f dtimep.c *.o libtws.a phoon deltime parsetime *.cat phoon.shar* core
  189. X
  190. Xphoon.shar:    phoon.shar1 phoon.shar2
  191. X
  192. Xphoon.shar1:    README Makefile deltime.c deltime.man dtime.c dtimep.lex
  193. X        shar -v -c -p X README Makefile deltime.c deltime.man dtime.c dtimep.lex > phoon.shar1
  194. X
  195. Xphoon.shar2:    lexedit.sed lexstring.c libtws.man parsetime.c phoon.c phoon.man tws.h
  196. X        shar -v -c -p X lexedit.sed lexstring.c libtws.man parsetime.c phoon.c phoon.man tws.h > phoon.shar2
  197. SHAR_EOF
  198. if test 2137 -ne "`wc -c < 'Makefile'`"
  199. then
  200.     echo shar: error transmitting "'Makefile'" '(should have been 2137 characters)'
  201. fi
  202. fi # end of overwriting check
  203. echo shar: extracting "'deltime.c'" '(2156 characters)'
  204. if test -f 'deltime.c'
  205. then
  206.     echo shar: will not over-write existing file "'deltime.c'"
  207. else
  208. sed 's/^X//' << \SHAR_EOF > 'deltime.c'
  209. X/* deltime.c - subtract date/times
  210. X
  211. Xver  date   who remarks
  212. X--- ------- --- -------------------------------------------------------------
  213. X01B 15nov86 JP  Modified to use twsubtract().
  214. X01A 08nov86 JP  Written.
  215. X
  216. XCopyright (C) 1986 by Jef Poskanzer.  Permission to use, copy,
  217. Xmodify, and distribute this software and its documentation for any
  218. Xpurpose and without fee is hereby granted, provided that this copyright
  219. Xnotice appear in all copies and in all supporting documentation.  No
  220. Xrepresentation is made about the suitability of this software for any
  221. Xpurpose.  It is provided "as is" without express or implied warranty.
  222. X
  223. X*/
  224. X
  225. Xstatic char copyright[] = "\nCopyright (C) 1986 by Jef Poskanzer.\n";
  226. X
  227. X
  228. X#include "tws.h"
  229. X#include <stdio.h>
  230. X
  231. X#define SECSPERMINUTE 60
  232. X#define SECSPERHOUR (60 * SECSPERMINUTE)
  233. X#define SECSPERDAY (24 * SECSPERHOUR)
  234. X
  235. Xmain( argc, argv )
  236. Xint argc;
  237. Xchar *argv[];
  238. X    {
  239. X    struct tws tws1, tws2, *twp;
  240. X    long delta, days, hours, minutes, secs;
  241. X    char *illdt = "illegal date/time: %s\n";
  242. X
  243. X    if ( argc == 2 )
  244. X    {
  245. X    twp = dparsetime( argv[1] );
  246. X    if ( twp == NULL || twp -> tw_flags & TW_JUNK )
  247. X        {
  248. X        fprintf( stderr, illdt, argv[1] );
  249. X        exit( 1 );
  250. X        }
  251. X    twscopy( &tws1, twp );
  252. X    twscopy( &tws2, dtwstime( ) );
  253. X    }
  254. X    else if ( argc == 3 )
  255. X    {
  256. X    twp = dparsetime( argv[1] );
  257. X    if ( twp == NULL || twp -> tw_flags & TW_JUNK )
  258. X        {
  259. X        fprintf( stderr, illdt, argv[1] );
  260. X        exit( 1 );
  261. X        }
  262. X    twscopy( &tws1, twp );
  263. X    twp = dparsetime( argv[2] );
  264. X    if ( twp == NULL || twp -> tw_flags & TW_JUNK )
  265. X        {
  266. X        fprintf( stderr, illdt, argv[2] );
  267. X        exit( 1 );
  268. X        }
  269. X    twscopy( &tws2, twp );
  270. X    }
  271. X    else
  272. X    {
  273. X    fprintf( stderr, "usage:  %s  <time>  [ <time2> ]\n", argv[0] );
  274. X    exit( 1 );
  275. X    }
  276. X    
  277. X    delta = twsubtract( &tws2, &tws1 );
  278. X    if ( delta < 0 )
  279. X    {
  280. X    printf( "-" );
  281. X    delta = -delta;
  282. X    }
  283. X
  284. X    days = delta / SECSPERDAY;
  285. X    delta = delta - days * SECSPERDAY;
  286. X    hours = delta / SECSPERHOUR;
  287. X    delta = delta - hours * SECSPERHOUR;
  288. X    minutes = delta / SECSPERMINUTE;
  289. X    delta = delta - minutes * SECSPERMINUTE;
  290. X    secs = delta;
  291. X
  292. X    printf( "%ld %2ld:%02ld:%02ld\n", days, hours, minutes, secs );
  293. X
  294. X    exit( 0 );
  295. X    }
  296. SHAR_EOF
  297. if test 2156 -ne "`wc -c < 'deltime.c'`"
  298. then
  299.     echo shar: error transmitting "'deltime.c'" '(should have been 2156 characters)'
  300. fi
  301. fi # end of overwriting check
  302. echo shar: extracting "'deltime.man'" '(803 characters)'
  303. if test -f 'deltime.man'
  304. then
  305.     echo shar: will not over-write existing file "'deltime.man'"
  306. else
  307. sed 's/^X//' << \SHAR_EOF > 'deltime.man'
  308. X.TH example 1 "08 November 1986"
  309. X.SH NAME
  310. Xdeltime \- compute a delta time
  311. X.SH SYNOPSIS
  312. X.in +.5i
  313. X.ti -.5i
  314. Xdeltime  <time>  \%[ <time2> ]
  315. X.in -.5i
  316. X.SH DESCRIPTION
  317. X.PP
  318. X.I Deltime
  319. Xcomputes the elapsed time between now and a
  320. Xspecified date/time, or between two specified date/times.
  321. XThe format for specifying date/times is pretty loose - basically
  322. Xthe same as the format for date/times in network mail.
  323. XJust be careful to put them in quotes if they contain spaces.
  324. XThe output format is dddd hh:mm:ss.
  325. X.PP
  326. XTimes earlier than 1970
  327. X.I can
  328. Xbe handled, because the internal Unix* time format is not used.
  329. XHowever, time spans greater than 66 years
  330. X.I cannot
  331. Xbe handled, because that's 2**31 seconds.
  332. X.SH "SEE\ ALSO"
  333. X.IR phoon(1),
  334. X.IR libtws(3)
  335. X.SH AUTHOR
  336. XJef Poskanzer
  337. X.SH NOTE
  338. X* Unix is a virus from outer space.
  339. SHAR_EOF
  340. if test 803 -ne "`wc -c < 'deltime.man'`"
  341. then
  342.     echo shar: error transmitting "'deltime.man'" '(should have been 803 characters)'
  343. fi
  344. fi # end of overwriting check
  345. echo shar: extracting "'dtime.c'" '(9035 characters)'
  346. if test -f 'dtime.c'
  347. then
  348.     echo shar: will not over-write existing file "'dtime.c'"
  349. else
  350. sed 's/^X//' << \SHAR_EOF > 'dtime.c'
  351. X/* dtime.c - routines to do ``ARPA-style'' time structures
  352. X
  353. Xver  date   who remarks
  354. X--- ------- --- -------------------------------------------------------------
  355. X01B 15nov86 JP  Thouroughly hacked by Jef Poskanzer.
  356. X01A ??????? MTR Original version from the MH 6.5 distribution, courtesy
  357. X              of Marshall Rose.
  358. X
  359. X*/
  360. X
  361. X
  362. X#include "tws.h"
  363. X#include <stdio.h>
  364. X#include <sys/types.h>
  365. X#include <time.h>
  366. X#ifdef  SYS5
  367. X#include <string.h>
  368. X#else SYS5
  369. X#include <strings.h>
  370. X#include <sys/timeb.h>
  371. X#endif SYS5
  372. X
  373. X#ifdef    SYS5
  374. Xextern int  daylight;
  375. Xextern long timezone;
  376. Xextern char *tzname[];
  377. X#endif    SYS5
  378. X
  379. X/*   */
  380. X
  381. X#define    abs(a) ( a >= 0 ? a : -a )
  382. X
  383. Xchar *tw_moty[] = {
  384. X    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  385. X    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL };
  386. X
  387. Xchar *tw_dotw[] = {
  388. X    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL };
  389. X
  390. Xchar *tw_ldotw[] = {
  391. X    "Sunday", "Monday", "Tuesday", "Wednesday",
  392. X    "Thursday", "Friday", "Saturday", NULL };
  393. X
  394. X/*   */
  395. X
  396. Xstatic struct zone
  397. X    {
  398. X    char *std;
  399. X    char *dst;
  400. X    int shift;
  401. X    }
  402. X    zones[] = {
  403. X    "GMT", "BST", 0,
  404. X    "EST", "EDT", -5,
  405. X    "CST", "CDT", -6,
  406. X    "MST", NULL, -7,
  407. X    "PST", "PDT", -8,
  408. X    "A", NULL, -1,
  409. X    "B", NULL, -2,
  410. X    "C", NULL, -3,
  411. X    "D", NULL, -4,
  412. X    "E", NULL, -5,
  413. X    "F", NULL, -6,
  414. X    "G", NULL, -7,
  415. X    "H", NULL, -8,
  416. X    "I", NULL, -9,
  417. X    "K", NULL, -10,
  418. X    "L", NULL, -11,
  419. X    "M", NULL, -12,
  420. X    "N", NULL, 1,
  421. X#ifndef    HUJI
  422. X    "O", NULL, 2,
  423. X#else    HUJI
  424. X    "JST", "JDT", 2,
  425. X#endif    HUJI
  426. X    "P", NULL, 3,
  427. X    "Q", NULL, 4,
  428. X    "R", NULL, 5,
  429. X    "S", NULL, 6,
  430. X    "T", NULL, 7,
  431. X    "U", NULL, 8,
  432. X    "V", NULL, 9,
  433. X    "W", NULL, 10,
  434. X    "X", NULL, 11,
  435. X    "Y", NULL, 12,
  436. X    NULL };
  437. X
  438. X#define CENTURY 19
  439. X
  440. Xlong time( );
  441. Xstruct tm *localtime( );
  442. X
  443. X/*   */
  444. X
  445. Xchar *dtimenow( )
  446. X    {
  447. X    long clock;
  448. X
  449. X    (void) time( &clock );
  450. X    return ( dtime( &clock ) );
  451. X    }
  452. X
  453. X
  454. Xchar *
  455. Xdctime( tw )
  456. Xstruct tws *tw;
  457. X    {
  458. X    static char buffer[25];
  459. X
  460. X    if ( tw == NULL )
  461. X    return ( NULL );
  462. X
  463. X    (void) sprintf( buffer, "%.3s %.3s %02d %02d:%02d:%02d %.4d\n",
  464. X        tw_dotw[tw -> tw_wday], tw_moty[tw -> tw_mon], tw -> tw_mday,
  465. X        tw -> tw_hour, tw -> tw_min, tw -> tw_sec,
  466. X        tw -> tw_year >= 100 ? tw -> tw_year : 1900 + tw -> tw_year );
  467. X
  468. X    return ( buffer );
  469. X    }
  470. X
  471. X/*   */
  472. X
  473. Xstruct tws *
  474. Xdtwstime( )
  475. X    {
  476. X    long clock;
  477. X
  478. X    (void) time( &clock );
  479. X    return ( dlocaltime( &clock ) );
  480. X    }
  481. X
  482. X
  483. Xstruct tws *
  484. Xdlocaltime( clock )
  485. Xlong *clock;
  486. X    {
  487. X    register struct tm *tm;
  488. X#ifndef SYS5
  489. X    struct timeb tb;
  490. X#endif not SYS5
  491. X    static struct tws tw;
  492. X
  493. X    if ( clock == NULL )
  494. X    return ( NULL );
  495. X    tw.tw_flags = TW_NULL;
  496. X
  497. X    tm = localtime( clock );
  498. X    tw.tw_sec = tm -> tm_sec;
  499. X    tw.tw_min = tm -> tm_min;
  500. X    tw.tw_hour = tm -> tm_hour;
  501. X    tw.tw_mday = tm -> tm_mday;
  502. X    tw.tw_mon = tm -> tm_mon;
  503. X    tw.tw_year = tm -> tm_year;
  504. X    tw.tw_wday = tm -> tm_wday;
  505. X    tw.tw_yday = tm -> tm_yday;
  506. X    if ( tm -> tm_isdst )
  507. X    tw.tw_flags |= TW_DST;
  508. X#ifndef  SYS5
  509. X    ftime( &tb );
  510. X    tw.tw_zone = -tb.timezone;
  511. X#else   SYS5
  512. X    tzset( );
  513. X    tw.tw_zone = -(timezone / 60);
  514. X#endif  SYS5
  515. X    tw.tw_flags &= ~TW_SDAY;
  516. X    tw.tw_flags |= TW_SEXP;
  517. X    tw.tw_clock = *clock;
  518. X
  519. X    return ( &tw );
  520. X    }
  521. X
  522. X
  523. Xstruct tws *
  524. Xdgmtime( clock )
  525. Xlong *clock;
  526. X    {
  527. X    register struct tm *tm;
  528. X    static struct tws tw;
  529. X
  530. X    if ( clock == NULL )
  531. X    return ( NULL );
  532. X    tw.tw_flags = TW_NULL;
  533. X
  534. X    tm = gmtime( clock );
  535. X    tw.tw_sec = tm -> tm_sec;
  536. X    tw.tw_min = tm -> tm_min;
  537. X    tw.tw_hour = tm -> tm_hour;
  538. X    tw.tw_mday = tm -> tm_mday;
  539. X    tw.tw_mon = tm -> tm_mon;
  540. X    tw.tw_year = tm -> tm_year;
  541. X    tw.tw_wday = tm -> tm_wday;
  542. X    tw.tw_yday = tm -> tm_yday;
  543. X    if ( tm -> tm_isdst )
  544. X    tw.tw_flags |= TW_DST;
  545. X    tw.tw_zone = 0;
  546. X    tw.tw_flags &= ~TW_SDAY;
  547. X    tw.tw_flags |= TW_SEXP;
  548. X    tw.tw_clock = *clock;
  549. X
  550. X    return( &tw );
  551. X    }
  552. X
  553. X/*   */
  554. X
  555. Xchar *
  556. Xdasctime( tw, flags )
  557. Xstruct tws *tw;
  558. Xint flags;
  559. X    {
  560. X    static char buffer[80], result[80];
  561. X
  562. X    if ( tw == NULL )
  563. X    return ( NULL );
  564. X
  565. X    (void) sprintf( buffer, "%02d %s %02d %02d:%02d:%02d %s",
  566. X        tw -> tw_mday, tw_moty[tw -> tw_mon], tw -> tw_year,
  567. X        tw -> tw_hour, tw -> tw_min, tw -> tw_sec,
  568. X        dtimezone( tw -> tw_zone, tw -> tw_flags | flags ) );
  569. X
  570. X    if ( (tw -> tw_flags & TW_SDAY) == TW_SEXP )
  571. X    (void) sprintf( result, "%s, %s", tw_dotw[tw -> tw_wday], buffer );
  572. X    else
  573. X    if ( (tw -> tw_flags & TW_SDAY) == TW_SNIL )
  574. X        (void) strcpy( result, buffer );
  575. X    else
  576. X        (void) sprintf( result, "%s (%s)", buffer, tw_dotw[tw -> tw_wday] );
  577. X
  578. X    return ( result );
  579. X    }
  580. X
  581. X/*   */
  582. X
  583. Xchar *
  584. Xdtimezone( offset, flags )
  585. Xint offset, flags;
  586. X    {
  587. X    register int hours, mins;
  588. X    register struct zone *z;
  589. X    static char buffer[10];
  590. X
  591. X    if ( offset < 0 )
  592. X    {
  593. X    mins = -((-offset) % 60);
  594. X    hours = -((-offset) / 60);
  595. X    }
  596. X    else
  597. X    {
  598. X    mins = offset % 60;
  599. X    hours = offset / 60;
  600. X    }
  601. X
  602. X    if ( !(flags & TW_ZONE) && mins == 0 )
  603. X    for ( z = zones; z -> std; z++ )
  604. X        if ( z -> shift == hours )
  605. X        return ( z -> dst && (flags & TW_DST) ? z -> dst : z -> std );
  606. X
  607. X#ifdef    DSTXXX
  608. X    if ( flags & TW_DST )
  609. X    hours += 1;
  610. X#endif    DSTXXX
  611. X    (void) sprintf( buffer, "%s%02d%02d",
  612. X        offset < 0 ? "-" : "+", abs( hours ), abs( mins ) );
  613. X    return ( buffer );
  614. X    }
  615. X
  616. X/*   */
  617. X
  618. Xvoid
  619. Xtwscopy( tb, tw )
  620. Xstruct tws *tb, *tw;
  621. X    {
  622. X#ifdef    notdef
  623. X    tb -> tw_sec = tw -> tw_sec;
  624. X    tb -> tw_min = tw -> tw_min;
  625. X    tb -> tw_hour = tw -> tw_hour;
  626. X    tb -> tw_mday = tw -> tw_mday;
  627. X    tb -> tw_mon = tw -> tw_mon;
  628. X    tb -> tw_year = tw -> tw_year;
  629. X    tb -> tw_wday = tw -> tw_wday;
  630. X    tb -> tw_yday = tw -> tw_yday;
  631. X    tb -> tw_zone = tw -> tw_zone;
  632. X    tb -> tw_clock = tw -> tw_clock;
  633. X    tb -> tw_flags = tw -> tw_flags;
  634. X#else    not notdef
  635. X    *tb = *tw;
  636. X#endif    not notdef
  637. X    }
  638. X
  639. X
  640. Xint
  641. Xtwsort( tw1, tw2 )
  642. Xstruct tws *tw1, *tw2;
  643. X    {
  644. X    register long c1, c2;
  645. X
  646. X    (void) twclock( tw1 );
  647. X    (void) twclock( tw2 );
  648. X
  649. X    return ( (c1 = tw1 -> tw_clock) > (c2 = tw2 -> tw_clock) ? 1
  650. X        : c1 == c2 ? 0 : -1 );
  651. X    }
  652. X
  653. X/*   */
  654. X
  655. X
  656. X/* Julian day number of the Unix* clock's origin, 01 Jan 1970. */
  657. X#define JD1970 2440587L
  658. X
  659. X
  660. Xlong
  661. Xtwjuliandate( tw )
  662. Xstruct tws *tw;
  663. X    {
  664. X    register int mday, mon, year;
  665. X    register long a, b;
  666. X    double jd;
  667. X
  668. X    if ( (mday = tw -> tw_mday) < 1 || mday > 31 ||
  669. X        (mon = tw -> tw_mon + 1) < 1 || mon > 12 ||
  670. X        (year = tw -> tw_year) < 1 || year > 10000 )
  671. X    return ( -1L );
  672. X    if ( year < 100 )
  673. X    year += CENTURY * 100;
  674. X
  675. X    if ( mon == 1 || mon == 2 )
  676. X    {
  677. X    --year;
  678. X    mon += 12;
  679. X    }
  680. X    if ( year < 1583 )
  681. X    return ( -1L );
  682. X    a = year / 100;
  683. X    b = 2 - a + a / 4;
  684. X    b += (long) ( (double) year * 365.25 );
  685. X    b += (long) ( 30.6001 * ( (double) mon + 1.0 ) );
  686. X    jd = mday + b + 1720994.5;
  687. X    return ( (long) jd );
  688. X    }
  689. X
  690. X
  691. Xlong
  692. Xtwsubdayclock( tw )
  693. Xstruct tws *tw;
  694. X    {
  695. X    register int i, sec, min, hour;
  696. X    register long result;
  697. X
  698. X    if ( (sec = tw -> tw_sec) < 0 || sec > 59 ||
  699. X        (min = tw -> tw_min) < 0 || min > 59 ||
  700. X        (hour = tw -> tw_hour) < 0 || hour > 23 )
  701. X    return ( -1L );
  702. X
  703. X    result = ( hour * 60 + min ) * 60 + sec;
  704. X    result -= 60 * tw -> tw_zone;
  705. X    if ( tw -> tw_flags & TW_DST )
  706. X    result -= 60 * 60;
  707. X
  708. X    return ( result );
  709. X    }
  710. X
  711. X
  712. Xlong
  713. Xtwclock( tw )
  714. Xstruct tws *tw;
  715. X    {
  716. X    register long jd, sdc, result;
  717. X
  718. X    if ( tw -> tw_clock != 0L )
  719. X    return ( tw -> tw_clock );
  720. X
  721. X    if ( ( jd = twjuliandate( tw ) ) == -1L )
  722. X    return ( tw -> tw_clock = -1L );
  723. X    if ( ( sdc = twsubdayclock( tw ) ) == -1L )
  724. X    return ( tw -> tw_clock = -1L );
  725. X
  726. X    result = ( jd - JD1970 ) * 24 * 60 * 60 + sdc;
  727. X
  728. X    return ( tw -> tw_clock = result );
  729. X    }
  730. X
  731. X/*   */
  732. X
  733. X/*** twsubtract - subtract tw2 from tw1, returning result in seconds
  734. X
  735. XThe point of this routine is that using twclock( tw1 ) - twclock( tw2 )
  736. Xwould limit you to dates after the Unix* Epoch ( 01 January 1970 ).  This
  737. Xroutine avoids that limit.  However, because the result is represented
  738. Xby 32 bits, it is still limited to a span of two billion seconds, which is
  739. Xabout 66 years.
  740. X
  741. X*/
  742. X
  743. Xlong
  744. Xtwsubtract( tw1, tw2 )
  745. Xstruct tws *tw1, *tw2;
  746. X    {
  747. X    register long jd1, jd2, sdc1, sdc2, result;
  748. X
  749. X    if ( ( jd1 = twjuliandate( tw1 ) ) == -1L )
  750. X    return ( 0L );
  751. X    if ( ( sdc1 = twsubdayclock( tw1 ) ) == -1L )
  752. X    return ( 0L );
  753. X
  754. X    if ( ( jd2 = twjuliandate( tw2 ) ) == -1L )
  755. X    return ( 0L );
  756. X    if ( ( sdc2 = twsubdayclock( tw2 ) ) == -1L )
  757. X    return ( 0L );
  758. X    
  759. X    result = ( jd1 - jd2 ) * 24 * 60 * 60 + ( sdc1 - sdc2 );
  760. X
  761. X    return ( result );
  762. X    }
  763. X
  764. X/*   */
  765. X
  766. X/*
  767. X *    Simple calculation of day of the week.  Algorithm used is Zeller's
  768. X *    congruence.  Currently, we assume if tw -> tw_year < 100
  769. X *    then the century is CENTURY.
  770. X */
  771. X
  772. Xset_dotw( tw )
  773. Xstruct tws *tw;
  774. X    {
  775. X    register int month, day, year, century;
  776. X
  777. X    month = tw -> tw_mon - 1;
  778. X    day = tw -> tw_mday;
  779. X    year = tw -> tw_year % 100;
  780. X    century = tw -> tw_year >= 100 ? tw -> tw_year / 100 : CENTURY;
  781. X
  782. X    if ( month <= 0 )
  783. X    {
  784. X    month += 12;
  785. X    if ( --year < 0 )
  786. X        {
  787. X        year += 100;
  788. X        century--;
  789. X        }
  790. X    }
  791. X
  792. X    tw -> tw_wday =
  793. X    ((26 * month - 2) / 10 + day + year + year / 4
  794. X        - 3 * century / 4 + 1) % 7;
  795. X
  796. X    tw -> tw_flags &= ~TW_SDAY;
  797. X    tw -> tw_flags |= TW_SIMP;
  798. X    }
  799. X
  800. X
  801. X/* * Unix is a virus from outer space. */
  802. SHAR_EOF
  803. if test 9035 -ne "`wc -c < 'dtime.c'`"
  804. then
  805.     echo shar: error transmitting "'dtime.c'" '(should have been 9035 characters)'
  806. fi
  807. fi # end of overwriting check
  808. echo shar: extracting "'dtimep.lex'" '(7327 characters)'
  809. if test -f 'dtimep.lex'
  810. then
  811.     echo shar: will not over-write existing file "'dtimep.lex'"
  812. else
  813. sed 's/^X//' << \SHAR_EOF > 'dtimep.lex'
  814. X%e 2000
  815. X%p 5000
  816. X%n 1000
  817. X%a 4000
  818. X%START    Z
  819. Xsun    (sun(day)?)
  820. Xmon    (mon(day)?)
  821. Xtue    (tue(sday)?)
  822. Xwed    (wed(nesday)?)
  823. Xthu    (thu(rsday)?)
  824. Xfri    (fri(day)?)
  825. Xsat    (sat(urday)?)
  826. X
  827. XDAY    ({sun}|{mon}|{tue}|{wed}|{thu}|{fri}|{sat})
  828. X
  829. Xjan    (jan(uary)?)
  830. Xfeb    (feb(ruary)?)
  831. Xmar    (mar(ch)?)
  832. Xapr    (apr(il)?)
  833. Xmay    (may)
  834. Xjun    (jun(e)?)
  835. Xjul    (jul(y)?)
  836. Xaug    (aug(ust)?)
  837. Xsep    (sep(tember)?)
  838. Xoct    (oct(ober)?)
  839. Xnov    (nov(ember)?)
  840. Xdec    (dec(ember)?)
  841. X
  842. XMONTH    ({jan}|{feb}|{mar}|{apr}|{may}|{jun}|{jul}|{aug}|{sep}|{oct}|{nov}|{dec})
  843. X
  844. Xw    ([ \t]*)
  845. XW    ([ \t]+)
  846. XD    ([0-9]?[0-9])
  847. Xd    [0-9]
  848. X%{
  849. X/* dtimep.lex - routines to do ``ARPA-style'' time parsing
  850. X
  851. Xver  date   who remarks
  852. X--- ------- --- -------------------------------------------------------------
  853. X01B 15nov86 JP  Thouroughly hacked by Jef Poskanzer.
  854. X01A ??????? MTR Original version from the MH 6.5 distribution, courtesy
  855. X              of Marshall Rose.
  856. X
  857. X*/
  858. X
  859. X#include "tws.h"
  860. X#include <ctype.h>
  861. X#include <sys/types.h>
  862. X#include <time.h>
  863. X#ifdef SYS5
  864. X#include <string.h>
  865. X#else SYS5
  866. X#include <strings.h>
  867. X#include <sys/timeb.h>
  868. X#endif SYS5
  869. X
  870. X#ifdef SYS5
  871. Xextern int  daylight;
  872. Xextern long timezone;
  873. Xextern char *tzname[];
  874. X#endif SYS5
  875. X
  876. X/*
  877. X * Table to convert month names to numeric month.  We use the
  878. X * fact that the low order 5 bits of the sum of the 2nd & 3rd
  879. X * characters of the name is a hash with no collisions for the 12
  880. X * valid month names.  (The mask to 5 bits maps any combination of
  881. X * upper and lower case into the same hash value).
  882. X */
  883. Xstatic int month_map[] = {
  884. X    0,
  885. X    6,    /* 1 - Jul */
  886. X    3,    /* 2 - Apr */
  887. X    5,    /* 3 - Jun */
  888. X    0,
  889. X    10,    /* 5 - Nov */
  890. X    0,
  891. X    1,    /* 7 - Feb */
  892. X    11,    /* 8 - Dec */
  893. X    0,
  894. X    0,
  895. X    0,
  896. X    0,
  897. X    0,
  898. X    0,
  899. X    0,    /*15 - Jan */
  900. X    0,
  901. X    0,
  902. X    0,
  903. X    2,    /*19 - Mar */
  904. X    0,
  905. X    8,    /*21 - Sep */
  906. X    0,
  907. X    9,    /*23 - Oct */
  908. X    0,
  909. X    0,
  910. X    4,    /*26 - May */
  911. X    0,
  912. X    7 };    /*28 - Aug */
  913. X/*
  914. X * Same trick for day-of-week using the hash function
  915. X *  (c1 & 7) + (c2 & 4)
  916. X */
  917. Xstatic int day_map[] = {
  918. X    0,
  919. X    0,
  920. X    0,
  921. X    6,    /* 3 - Sat */
  922. X    4,    /* 4 - Thu */
  923. X    0,
  924. X    5,    /* 6 - Fri */
  925. X    0,    /* 7 - Sun */
  926. X    2,    /* 8 - Tue */
  927. X    1    /* 9 - Mon */,
  928. X    0,
  929. X    3 };    /*11 - Wed */
  930. X#define SETDAY tw.tw_wday= day_map[(cp[0] & 7) + (cp[1] & 4)];\
  931. X        tw.tw_flags |= TW_SEXP;\
  932. X        cp += 2;
  933. X#define SETMONTH tw.tw_mon = month_map[(cp[0] + cp[1]) & 0x1f]; gotdate++;\
  934. X         cp += 2;\
  935. X         SKIPD;
  936. X#define CVT1OR2 (i=(*cp++ - '0'), isdigit(*cp)? i*10 + (*cp++ - '0') : i)
  937. X#define CVT2 ( (*cp++ - '0')*10 + (*cp++ - '0') )
  938. X#define CVT3 ( ( (*cp++ - '0')*10 + (*cp++ - '0') )*10 + (*cp++ - '0') )
  939. X#define CVT4 ( ( ( (*cp++ - '0')*10 + (*cp++ - '0') )*10 + (*cp++ - '0') )*10 + (*cp++ - '0') )
  940. X#define SKIPD while ( ! isdigit( *cp++ ) ) ; --cp;
  941. X#define ZONE(x) tw.tw_zone=(x);
  942. X#define ZONED(x) tw.tw_zone=(x); tw.tw_flags |= TW_DST;
  943. X#define LC(c) (isupper( c ) ? tolower( c ) : ( c ))
  944. X%}
  945. X%%
  946. X%{
  947. Xstruct tws *
  948. Xdparsetime( str )
  949. Xchar *str;
  950. X    {
  951. X    register int i;
  952. X    static struct tws tw;
  953. X    register char *cp;
  954. X    register int gotdate = 0;
  955. X#ifndef SYS5
  956. X    struct timeb    tb;
  957. X#endif not SYS5
  958. X    long clock;
  959. X
  960. X    start_cond = 0;
  961. X
  962. X    /* Zero out the struct. */
  963. X    bzero( (char *) &tw, sizeof tw );
  964. X
  965. X    /* Set default time zone. */
  966. X#ifndef SYS5
  967. X    ftime( &tb );
  968. X    tw.tw_zone = -tb.timezone;
  969. X#else SYS5
  970. X    tzset( );
  971. X    tw.tw_zone = -(timezone / 60);
  972. X#endif SYS5
  973. X
  974. X    for ( ; ; )
  975. X    switch ( cp = str, lex_string( &str, start_cond ) )
  976. X        {
  977. X        case -1:
  978. X        if ( ! gotdate )
  979. X            return ( NULL );
  980. X        tw.tw_flags |= TW_JUNK;
  981. X        /* fall through */
  982. X        case 0:
  983. X        if ( tw.tw_year == 0 )
  984. X            {
  985. X            /* Set default year. */
  986. X            time( &clock );
  987. X            tw.tw_year = localtime( &clock ) -> tm_year;
  988. X            }
  989. X        return ( &tw );
  990. X
  991. X%}
  992. X{DAY}","?{w}                SETDAY;
  993. X"("{DAY}")"(","?)            cp++, SETDAY;
  994. X
  995. X{D}(("-"{D}"-")|("/"{D}"/")){D}?{d}{d}{w}    {
  996. X#ifdef EUROPE
  997. X                    tw.tw_mday = CVT1OR2; cp++;
  998. X                    tw.tw_mon  = CVT1OR2 - 1; cp++;
  999. X#else EUROPE
  1000. X                    tw.tw_mon = CVT1OR2 - 1; cp++;
  1001. X                    tw.tw_mday  = CVT1OR2; cp++;
  1002. X#endif EUROPE
  1003. X                    for ( i = 0; isdigit( *cp ); )
  1004. X                        i = i * 10 + (*cp++ - '0');
  1005. X                    tw.tw_year = i;
  1006. X                    gotdate++;
  1007. X                    }
  1008. X{D}("/"|"-"){D}{w}            {
  1009. X#ifdef EUROPE
  1010. X                    tw.tw_mday = CVT1OR2; cp++;
  1011. X                    tw.tw_mon  = CVT1OR2 - 1;
  1012. X#else EUROPE
  1013. X                    tw.tw_mon = CVT1OR2 - 1; cp++;
  1014. X                    tw.tw_mday  = CVT1OR2;
  1015. X#endif EUROPE
  1016. X                    gotdate++;
  1017. X                    }
  1018. X{D}(("-"{MONTH}"-")|(" "{MONTH}" ")|({MONTH})){D}?{d}{d}({W}at)?{w}    {
  1019. X                    tw.tw_mday = CVT1OR2;
  1020. X                    while ( ! isalpha( *cp++ ) )
  1021. X                        ;
  1022. X                    SETMONTH;
  1023. X                    for ( i = 0; isdigit( *cp ); )
  1024. X                        i = i * 10 + (*cp++ - '0');
  1025. X                    tw.tw_year = i;
  1026. X                    gotdate++;
  1027. X                    }
  1028. X{D}"-"?{MONTH}({W}at)?{w}        {
  1029. X                    tw.tw_mday = CVT1OR2;
  1030. X                    while ( ! isalpha( *cp++ ) )
  1031. X                        ;
  1032. X                    SETMONTH;
  1033. X                    gotdate++;
  1034. X                    }
  1035. X{MONTH}{W}{D}","{W}{D}?{d}{d}{w}    {
  1036. X                    cp++;
  1037. X                    SETMONTH;
  1038. X                    tw.tw_mday = CVT1OR2;
  1039. X                    SKIPD;
  1040. X                    for ( i = 0; isdigit( *cp ); )
  1041. X                        i = i * 10 + (*cp++ - '0');
  1042. X                    tw.tw_year = i;
  1043. X                    gotdate++;
  1044. X                    }
  1045. X{MONTH}{W}{D}{w}            {
  1046. X                    cp++;
  1047. X                    SETMONTH;
  1048. X                    tw.tw_mday = CVT1OR2;
  1049. X                    gotdate++;
  1050. X                    }
  1051. X
  1052. X{D}:{D}:{D}({w}am)?{w}            {
  1053. X                    tw.tw_hour = CVT1OR2; cp++;
  1054. X                    tw.tw_min  = CVT1OR2; cp++;
  1055. X                    tw.tw_sec  = CVT1OR2;
  1056. X                    BEGIN Z;
  1057. X                    }
  1058. X{D}:{D}:{D}{w}pm{w}            {
  1059. X                    tw.tw_hour = CVT1OR2 + 12; cp++;
  1060. X                    tw.tw_min  = CVT1OR2; cp++;
  1061. X                    tw.tw_sec  = CVT1OR2;
  1062. X                    BEGIN Z;
  1063. X                    }
  1064. X{D}:{D}({w}am)?{w}            {
  1065. X                    tw.tw_hour = CVT1OR2; cp++;
  1066. X                    tw.tw_min  = CVT1OR2;
  1067. X                    BEGIN Z;
  1068. X                    }
  1069. X{D}:{D}{w}pm{w}                {
  1070. X                    tw.tw_hour = CVT1OR2 + 12; cp++;
  1071. X                    tw.tw_min  = CVT1OR2;
  1072. X                    BEGIN Z;
  1073. X                    }
  1074. X[0-2]{d}{d}{d}{d}{d}{w}            {
  1075. X                    tw.tw_hour = CVT1OR2;
  1076. X                    tw.tw_min  = CVT1OR2;
  1077. X                    tw.tw_sec  = CVT1OR2;
  1078. X                    BEGIN Z;
  1079. X                    }
  1080. X[0-2]{d}{d}{d}{w}            {
  1081. X                    tw.tw_hour = CVT1OR2;
  1082. X                    tw.tw_min  = CVT1OR2;
  1083. X                    BEGIN Z;
  1084. X                    }
  1085. X<Z>"-"?ut                ZONE(0 * 60);
  1086. X<Z>"-"?gmt                ZONE(0 * 60);
  1087. X<Z>"-"?jst                ZONE(2 * 60);
  1088. X<Z>"-"?jdt                ZONED(2 * 60);
  1089. X<Z>"-"?est                ZONE(-5 * 60);
  1090. X<Z>"-"?edt                ZONED(-5 * 60);
  1091. X<Z>"-"?cst                ZONE(-6 * 60);
  1092. X<Z>"-"?cdt                ZONED(-6 * 60);
  1093. X<Z>"-"?mst                ZONE(-7 * 60);
  1094. X<Z>"-"?mdt                ZONED(-7 * 60);
  1095. X<Z>"-"?pst                ZONE(-8 * 60);
  1096. X<Z>"-"?pdt                ZONED(-8 * 60);
  1097. X<Z>"-"?nst                ZONE(-(3 * 60 + 30));
  1098. X<Z>"-"?ast                ZONE(-4 * 60);
  1099. X<Z>"-"?adt                ZONED(-4 * 60);
  1100. X<Z>"-"?yst                ZONE(-9 * 60);
  1101. X<Z>"-"?ydt                ZONED(-9 * 60);
  1102. X<Z>"-"?hst                ZONE(-10 * 60);
  1103. X<Z>"-"?hdt                ZONED(-10 * 60);
  1104. X<Z>"-"?bst                ZONED(-1 * 60);
  1105. X<Z>[a-i]                tw.tw_zone = 60 * (('a'-1) - LC (*cp));
  1106. X<Z>[k-m]                tw.tw_zone = 60 * ('a' - LC (*cp));
  1107. X<Z>[n-y]                tw.tw_zone = 60 * (LC (*cp) - 'm');
  1108. X<Z>"+"[0-1]{d}{d}{d}            {
  1109. X                    cp++;
  1110. X                    tw.tw_zone = ((cp[0] * 10 + cp[1])
  1111. X                             -('0' * 10   + '0'))*60
  1112. X                            +((cp[2] * 10 + cp[3])
  1113. X                             -('0' * 10   + '0'));
  1114. X#ifdef DSTXXX
  1115. X                    zonehack (&tw);
  1116. X#endif DSTXXX
  1117. X                    cp += 4;
  1118. X                    }
  1119. X<Z>"-"[0-1]{d}{d}{d}            {
  1120. X                    cp++;
  1121. X                    tw.tw_zone = (('0' * 10   + '0')
  1122. X                             -(cp[0] * 10 + cp[1]))*60
  1123. X                            +(('0' * 10   + '0')
  1124. X                             -(cp[2] * 10 + cp[3]));
  1125. X#ifdef DSTXXX
  1126. X                    zonehack (&tw);
  1127. X#endif DSTXXX
  1128. X                    cp += 4;
  1129. X                    }
  1130. X
  1131. X<Z>{W}{d}{d}{d}{d}            {
  1132. X                    SKIPD;
  1133. X                    tw.tw_year = CVT4;
  1134. X                    }
  1135. X\n    |
  1136. X{W}    ;
  1137. X%%
  1138. X
  1139. X#ifdef DSTXXX
  1140. Xstatic
  1141. Xzonehack( tw )
  1142. Xregister struct tws *tw;
  1143. X    {
  1144. X    register struct tm *tm;
  1145. X
  1146. X    if ( twclock( tw ) == -1L )
  1147. X    return;
  1148. X
  1149. X    tm = localtime( &tw -> tw_clock );
  1150. X    if ( tm -> tm_isdst )
  1151. X    {
  1152. X    tw -> tw_flags |= TW_DST;
  1153. X    tw -> tw_zone -= 60;
  1154. X    }
  1155. X    }
  1156. X#endif DSTXXX
  1157. X
  1158. X
  1159. X#ifdef SYS5
  1160. X/* Not all SYS5's have bzero( ). */
  1161. X
  1162. Xbzero( b, length )
  1163. Xchar *b;
  1164. Xint length;
  1165. X    {
  1166. X    while ( length-- > 0 )
  1167. X    *b++ = 0;
  1168. X    }
  1169. X#endif
  1170. SHAR_EOF
  1171. if test 7327 -ne "`wc -c < 'dtimep.lex'`"
  1172. then
  1173.     echo shar: error transmitting "'dtimep.lex'" '(should have been 7327 characters)'
  1174. fi
  1175. fi # end of overwriting check
  1176. echo shar: extracting "'lexedit.sed'" '(356 characters)'
  1177. if test -f 'lexedit.sed'
  1178. then
  1179.     echo shar: will not over-write existing file "'lexedit.sed'"
  1180. else
  1181. sed 's/^X//' << \SHAR_EOF > 'lexedit.sed'
  1182. X2,/^extern int yylineno;$/c\
  1183. Xstatic int start_cond = 0;\
  1184. X#define BEGIN start_cond =
  1185. X/^struct yysvf \*yyestate;$/,/^extern struct yysvf yysvec/d
  1186. X/^# define YYNEWLINE /,/^int nstr;/d
  1187. X/^while((nstr = yylook()/,/^if(yywrap()) /d
  1188. X/^case -1:$/,/^fprintf(yyout,"bad switch yylook /c\
  1189. X    default: return(0);
  1190. X/^struct yysvf *yybgin = yysvec+1;$/d
  1191. X/^int yylineno /,$d
  1192. SHAR_EOF
  1193. if test 356 -ne "`wc -c < 'lexedit.sed'`"
  1194. then
  1195.     echo shar: error transmitting "'lexedit.sed'" '(should have been 356 characters)'
  1196. fi
  1197. fi # end of overwriting check
  1198. echo shar: extracting "'lexstring.c'" '(3765 characters)'
  1199. if test -f 'lexstring.c'
  1200. then
  1201.     echo shar: will not over-write existing file "'lexstring.c'"
  1202. else
  1203. sed 's/^X//' << \SHAR_EOF > 'lexstring.c'
  1204. X#include <stdio.h>
  1205. X#include <ctype.h>
  1206. X
  1207. X#define YYLERR yysvec
  1208. X#define YYTYPE int
  1209. X#define YYLMAX 256
  1210. X
  1211. Xstruct yysvf { 
  1212. X    struct yywork *yystoff;
  1213. X    struct yysvf *yyother;
  1214. X    int *yystops;
  1215. X};
  1216. X
  1217. Xstruct yywork { 
  1218. X    YYTYPE    verify;
  1219. X    YYTYPE    advance; 
  1220. X}; 
  1221. X
  1222. Xextern int yyvstop[];
  1223. Xextern struct yywork yycrank[];
  1224. Xextern struct yysvf yysvec[];
  1225. Xextern struct yywork *yytop;
  1226. Xextern char yymatch[];
  1227. Xextern char yyextra[];
  1228. X
  1229. X#ifdef LEXDEBUG
  1230. Xstatic int debug = 0;
  1231. X#endif LEXDEBUG
  1232. X
  1233. Xlex_string( strptr, start_cond)
  1234. X    char    **strptr;
  1235. X    int    start_cond;
  1236. X{
  1237. X    register struct yysvf *state, **lsp;
  1238. X    register struct yywork *tran;
  1239. X    register int ch;
  1240. X    register char    *cp = *strptr;
  1241. X    register int    *found;
  1242. X    struct    yysvf *yylstate[YYLMAX];
  1243. X
  1244. X    /* start off machines */
  1245. X    lsp = yylstate;
  1246. X    state = yysvec+1+start_cond;
  1247. X    for (;;){
  1248. X# ifdef LEXDEBUG
  1249. X        if(debug)
  1250. X            fprintf(stderr,"state %d\n",state-yysvec-1);
  1251. X# endif
  1252. X        tran = state->yystoff;
  1253. X        if(tran == yycrank)
  1254. X            /* may not be any transitions */
  1255. X            if (state->yyother == 0 ||
  1256. X                state->yyother->yystoff == yycrank)
  1257. X                break;
  1258. X
  1259. X        ch = *cp++;
  1260. X#ifdef ONECASE
  1261. X        if (isupper(ch) )
  1262. X            ch = tolower(ch);
  1263. X#endif ONECASE
  1264. Xtryagain:
  1265. X# ifdef LEXDEBUG
  1266. X        if(debug){
  1267. X            fprintf(stderr,"char ");
  1268. X            allprint(ch);
  1269. X            putchar('\n');
  1270. X        }
  1271. X# endif
  1272. X        if ( tran > yycrank){
  1273. X            tran += ch;
  1274. X            if (tran <= yytop && tran->verify+yysvec == state){
  1275. X                if ((state = tran->advance+yysvec) == YYLERR){
  1276. X                    /* error transitions */
  1277. X                    --cp;
  1278. X                    break;
  1279. X                }
  1280. X                *lsp++ = state;
  1281. X                goto contin;
  1282. X            }
  1283. X
  1284. X        } else if(tran < yycrank) {
  1285. X            /* r < yycrank */
  1286. X            tran = yycrank+(yycrank-tran) + ch;
  1287. X# ifdef LEXDEBUG
  1288. X            if (debug)
  1289. X                fprintf(stderr,"compressed state\n");
  1290. X# endif
  1291. X            if(tran <= yytop && tran->verify+yysvec == state){
  1292. X                if ((state = tran->advance+yysvec) == YYLERR)
  1293. X                    /* error transitions */
  1294. X                    break;
  1295. X
  1296. X                *lsp++ = state;
  1297. X                goto contin;
  1298. X            }
  1299. X            tran += (yymatch[ch] - ch);
  1300. X# ifdef LEXDEBUG
  1301. X            if(debug){
  1302. X                fprintf(stderr,"try fall back character ");
  1303. X                allprint(yymatch[ch]);
  1304. X                putchar('\n');
  1305. X            }
  1306. X# endif
  1307. X            if(tran <= yytop && tran->verify+yysvec == state){
  1308. X                if(tran->advance+yysvec == YYLERR)
  1309. X                    /* error transition */
  1310. X                    break;
  1311. X
  1312. X                *lsp++ = state = tran->advance+yysvec;
  1313. X                goto contin;
  1314. X            }
  1315. X        }
  1316. X        if ((state = state->yyother) &&
  1317. X            (tran = state->yystoff) != yycrank){
  1318. X# ifdef LEXDEBUG
  1319. X            if(debug)
  1320. X                fprintf(stderr,"fall back to state %d\n",
  1321. X                    state-yysvec-1);
  1322. X# endif
  1323. X            goto tryagain;
  1324. X        } else
  1325. X            break;
  1326. X
  1327. Xcontin:
  1328. X# ifdef LEXDEBUG
  1329. X        if(debug){
  1330. X            fprintf(stderr,"state %d char ",state-yysvec-1);
  1331. X            allprint(ch);
  1332. X            putchar('\n');
  1333. X        }
  1334. X# endif
  1335. X        ;
  1336. X    }
  1337. X# ifdef LEXDEBUG
  1338. X    if(debug){
  1339. X        fprintf(stderr,"stopped at %d with ",*(lsp-1)-yysvec-1);
  1340. X        allprint(ch);
  1341. X        putchar('\n');
  1342. X    }
  1343. X# endif
  1344. X    while (lsp-- > yylstate){
  1345. X        if (*lsp != 0 && (found= (*lsp)->yystops) && *found > 0){
  1346. X            if(yyextra[*found]){
  1347. X                /* must backup */
  1348. X                ch = -*found;
  1349. X                do {
  1350. X                    while (*found && *found++ != ch)
  1351. X                        ;
  1352. X                 } while (lsp > yylstate &&
  1353. X                      (found = (*--lsp)->yystops));
  1354. X            }
  1355. X# ifdef LEXDEBUG
  1356. X            if(debug){
  1357. X                fprintf(stderr,"\nmatch ");
  1358. X                for ( cp = *strptr;
  1359. X                      cp <= ((*strptr)+(lsp-yylstate));
  1360. X                      cp++)
  1361. X                    allprint( *cp );
  1362. X                fprintf(stderr," action %d\n",*found);
  1363. X            }
  1364. X# endif
  1365. X            *strptr += (lsp - yylstate + 1);
  1366. X            return(*found);
  1367. X        }
  1368. X    }
  1369. X    /* the string didn't match anything - if we're looking at
  1370. X     * eos, just return 0.  Otherwise, bump the string pointer
  1371. X     * and return -1.
  1372. X     */
  1373. X# ifdef LEXDEBUG
  1374. X    if(debug)
  1375. X        fprintf(stderr,"\nno match\n");
  1376. X#endif LEXDEBUG
  1377. X    if ( **strptr ) {
  1378. X        (*strptr)++;
  1379. X        return (-1);
  1380. X    }
  1381. X    return (0);
  1382. X}
  1383. X
  1384. X#ifdef LEXDEBUG
  1385. Xallprint(c)
  1386. X    char c;
  1387. X{
  1388. X    if ( c < 32 ) {
  1389. X        putc( '^', stderr );
  1390. X        c += 32;
  1391. X    } else if ( c == 127 ) {
  1392. X        putc( '^', stderr );
  1393. X        c = '?';
  1394. X    }
  1395. X    putc( c, stderr );
  1396. X}
  1397. X#endif LEXDEBUG
  1398. SHAR_EOF
  1399. if test 3765 -ne "`wc -c < 'lexstring.c'`"
  1400. then
  1401.     echo shar: error transmitting "'lexstring.c'" '(should have been 3765 characters)'
  1402. fi
  1403. fi # end of overwriting check
  1404. echo shar: extracting "'libtws.man'" '(2241 characters)'
  1405. if test -f 'libtws.man'
  1406. then
  1407.     echo shar: will not over-write existing file "'libtws.man'"
  1408. else
  1409. sed 's/^X//' << \SHAR_EOF > 'libtws.man'
  1410. X.TH libtws 3 "08 November 1986"
  1411. X.SH NAME
  1412. Xlibtws \- alternate date and time routines including parsing
  1413. X.SH SYNOPSIS
  1414. X.nf
  1415. X.fc ^ ~
  1416. X.ta \w'char *dtimezone( offset, flags );  'u
  1417. Xinclude "tws.h"
  1418. X.PP
  1419. X^struct tws *dlocaltime( clock );~^/* local clock into tws */
  1420. Xlong *clock;
  1421. X.PP
  1422. X^struct tws *gmtime( clock );~^/* GMT clock into tws */
  1423. Xlong *clock;
  1424. X.PP
  1425. X^char *dtime( clock );~^/* clock into string */
  1426. Xlong *clock;
  1427. X.PP
  1428. X^long twclock( t );~^/* tws into clock */
  1429. Xstruct tws *t;
  1430. X.PP
  1431. X^long twjuliandate( t );~^/* tws into Julian day number */
  1432. Xstruct tws *t;
  1433. X.PP
  1434. X^struct tws *dparsetime( str );~^/* string into tws */
  1435. Xchar *str;
  1436. X.PP
  1437. X^char *dctime( t );~^/* tws into string */
  1438. Xstruct tws *t;
  1439. X.PP
  1440. X^char *dasctime( t, flags );~^/* tws into string */
  1441. Xstruct tws *t;
  1442. Xint flags;
  1443. X.PP
  1444. X^char *dtimezone( offset, flags );~^/* timezone into string */
  1445. Xint offset, flags;
  1446. X.PP
  1447. X^char *dtwszone( t );~^/* tws's timezone into string */
  1448. Xstruct tws *t;
  1449. X.PP
  1450. X^char *dtimemow( );~^/* current time into string */
  1451. X.PP
  1452. X^struct tws *dtwstime( );~^/* current time into tws */
  1453. X.PP
  1454. X^void twscopy( tot, fromt );~^/* copy a tws */
  1455. Xstruct tws *tot, *fromt;
  1456. X.PP
  1457. X^int twsort( t1, t2 );~^/* compare two tws's */
  1458. Xstruct tws *t1, *t2;
  1459. X.PP
  1460. X^long twsubtract( t1, t2 );~^/* seconds between t2 and t1 */
  1461. Xstruct tws *t1, *t2;
  1462. X.fi
  1463. X.SH DESCRIPTION
  1464. X.I Libtws
  1465. Xis a fairly complete date/time library.
  1466. XUnlike the standard Unix* date/time routines,
  1467. X.I libtws
  1468. Xwill parse date/time strings into internal form.
  1469. XThe format for specifying date/time strings is pretty loose - basically
  1470. Xthe same as the format for date/times in network mail.
  1471. X.PP
  1472. XMost of the routines do not use the Unix* "clock" time
  1473. Xformat, and therefore are not limited to dates after 01 January 1970.
  1474. XIn particular, twsubtract() lets you subtract two dates without
  1475. Xconverting them to "clock" form.
  1476. X.SH "SEE\ ALSO"
  1477. X.IR ctime(3),
  1478. X.IR time(3)
  1479. X.SH AUTHOR
  1480. XMost of
  1481. X.I libtws
  1482. Xcame from version 6.5 of the MH message
  1483. Xhandling system, courtesy of Marshall Rose.
  1484. XSome improvements (?) were added by Jef Poskanzer.
  1485. X.SH BUGS
  1486. XThe return values point to static data whose contents are overwritten
  1487. Xby the next call.
  1488. X.PP
  1489. XThe basic Unix* time format (clock) only goes back to 1970, limiting
  1490. Xapplications somewhat.
  1491. X.SH NOTE
  1492. X* Unix is a virus from outer space.
  1493. SHAR_EOF
  1494. if test 2241 -ne "`wc -c < 'libtws.man'`"
  1495. then
  1496.     echo shar: error transmitting "'libtws.man'" '(should have been 2241 characters)'
  1497. fi
  1498. fi # end of overwriting check
  1499. echo shar: extracting "'parsetime.c'" '(1756 characters)'
  1500. if test -f 'parsetime.c'
  1501. then
  1502.     echo shar: will not over-write existing file "'parsetime.c'"
  1503. else
  1504. sed 's/^X//' << \SHAR_EOF > 'parsetime.c'
  1505. X/* parsetime.c - parse a date/time and display the results
  1506. X
  1507. Xver  date   who remarks
  1508. X--- ------- --- -------------------------------------------------------------
  1509. X01A 15nov86 JP  Written.
  1510. X
  1511. XCopyright (C) 1986 by Jef Poskanzer.  Permission to use, copy,
  1512. Xmodify, and distribute this software and its documentation for any
  1513. Xpurpose and without fee is hereby granted, provided that this copyright
  1514. Xnotice appear in all copies and in all supporting documentation.  No
  1515. Xrepresentation is made about the suitability of this software for any
  1516. Xpurpose.  It is provided "as is" without express or implied warranty.
  1517. X
  1518. X*/
  1519. X
  1520. Xstatic char copyright[] = "\nCopyright (C) 1986 by Jef Poskanzer.\n";
  1521. X
  1522. X
  1523. X#include "tws.h"
  1524. X#include <stdio.h>
  1525. X
  1526. X
  1527. Xmain( argc, argv )
  1528. Xint argc;
  1529. Xchar *argv[];
  1530. X    {
  1531. X    char buf[200];
  1532. X    int i;
  1533. X    struct tws *twp;
  1534. X
  1535. X    strcpy( buf, "" );
  1536. X    for ( i = 1; i < argc; i++ )
  1537. X    {
  1538. X    if ( i > 1 )
  1539. X        strcat( buf, " " );
  1540. X    strcat( buf, argv[i] );
  1541. X    }
  1542. X
  1543. X    twp = dparsetime( buf );
  1544. X    if ( twp == NULL )
  1545. X    {
  1546. X    fprintf( stderr, "illegal date/time: %s\n", buf );
  1547. X    exit( 1 );
  1548. X    }
  1549. X
  1550. X    printf( "dparsetime( \"%s\" ):\n", buf );
  1551. X    printf( "  tw_sec = %d\n", twp->tw_sec );
  1552. X    printf( "  tw_min = %d\n", twp->tw_min );
  1553. X    printf( "  tw_hour = %d\n", twp->tw_hour );
  1554. X    printf( "  tw_mday = %d\n", twp->tw_mday );
  1555. X    printf( "  tw_mon = %d\n", twp->tw_mon );
  1556. X    printf( "  tw_year = %d\n", twp->tw_year );
  1557. X    printf( "  tw_wday = %d\n", twp->tw_wday );
  1558. X    printf( "  tw_yday = %d\n", twp->tw_yday );
  1559. X    printf( "  tw_zone = %d\n", twp->tw_zone );
  1560. X    printf( "  tw_clock = %ld\n", twp->tw_clock );
  1561. X    printf( "  tw_flags = %d (0x%04x)\n", twp->tw_flags, twp->tw_flags );
  1562. X    printf( "\n" );
  1563. X    printf( "dasctime: %s\n", dasctime( twp, 0 ) );
  1564. X
  1565. X    exit( 0 );
  1566. X    }
  1567. SHAR_EOF
  1568. if test 1756 -ne "`wc -c < 'parsetime.c'`"
  1569. then
  1570.     echo shar: error transmitting "'parsetime.c'" '(should have been 1756 characters)'
  1571. fi
  1572. fi # end of overwriting check
  1573. echo shar: extracting "'phoon.c'" '(12899 characters)'
  1574. if test -f 'phoon.c'
  1575. then
  1576.     echo shar: will not over-write existing file "'phoon.c'"
  1577. else
  1578. sed 's/^X//' << \SHAR_EOF > 'phoon.c'
  1579. X/* phoon - show the phase of the moon
  1580. X
  1581. Xver  date   who remarks
  1582. X--- ------- --- -------------------------------------------------------------
  1583. X01C 26jan87 JP  Added backgrounds for 29 and 18 lines.
  1584. X01B 28dec86 JP  Added -l flag, and backgrounds for 19 and 24 lines.
  1585. X01A 08nov86 JP  Translated from the ratfor version of 12nov85, which itself
  1586. X                  was translated from the Pascal version of 05apr79.
  1587. X
  1588. XCopyright (C) 1986 by Jeffrey A. Poskanzer.  Permission to use, copy,
  1589. Xmodify, and distribute this software and its documentation for any
  1590. Xpurpose and without fee is hereby granted, provided that this copyright
  1591. Xnotice appear in all copies and in all supporting documentation.  No
  1592. Xrepresentation is made about the suitability of this software for any
  1593. Xpurpose.  It is provided "as is" without express or implied warranty.
  1594. X
  1595. X*/
  1596. X
  1597. Xstatic char copyright[] = "\nCopyright (C) 1986 by Jeffrey A. Poskanzer.\n";
  1598. X
  1599. X
  1600. X#include <stdio.h>
  1601. X#include <math.h>
  1602. X#include "tws.h"
  1603. X
  1604. X
  1605. X/* Global defines and declarations. */
  1606. X
  1607. X#define SECSPERMINUTE 60
  1608. X#define SECSPERHOUR (60 * SECSPERMINUTE)
  1609. X#define SECSPERDAY (24 * SECSPERHOUR)
  1610. X
  1611. X#define PI 3.14159
  1612. X
  1613. X#define DEFAULTNUMLINES 23
  1614. X#define MOONSTARTCOL 18
  1615. X#define QUARTERLITLEN 16
  1616. X#define QUARTERLITLENPLUSONE 17
  1617. X
  1618. X/* If you change the aspect ratio, the canned backgrounds won't work. */
  1619. X#define ASPECTRATIO 0.5
  1620. X
  1621. X/* Main program. */
  1622. X
  1623. Xmain( argc, argv, envp )
  1624. Xint argc;
  1625. Xchar *argv[], *envp[];
  1626. X    {
  1627. X    struct tws t, *twp;
  1628. X    char buf[100];
  1629. X    int numlines, argi, i;
  1630. X    char *usage = "usage:  %s  [ -l <lines> ]  [ <date/time> ]\n";
  1631. X
  1632. X    /* Parge args. */
  1633. X    argi = 1;
  1634. X    /* Check for -l flag. */
  1635. X    numlines = DEFAULTNUMLINES;
  1636. X    if ( argc - argi >= 1 )
  1637. X    {
  1638. X    if ( argv[argi][0] == '-' )
  1639. X        {
  1640. X        if ( argv[argi][1] != 'l' | argv[argi][2] != '\0' )
  1641. X        {
  1642. X        fprintf( stderr, usage, argv[0] );
  1643. X        exit( 1 );
  1644. X        }
  1645. X        else
  1646. X        {
  1647. X        if ( argc - argi < 2 )
  1648. X            {
  1649. X            fprintf( stderr, usage, argv[0] );
  1650. X            exit( 1 );
  1651. X            }
  1652. X        if ( sscanf( argv[argi + 1], "%d", &numlines ) != 1 )
  1653. X            {
  1654. X            fprintf( stderr, usage, argv[0] );
  1655. X            exit( 1 );
  1656. X            }
  1657. X        argi += 2;
  1658. X        }
  1659. X        }
  1660. X    }
  1661. X
  1662. X    /* Figure out what date and time to use. */
  1663. X    if ( argc - argi == 0 )
  1664. X    {
  1665. X    /* No arguments present - use the current date and time. */
  1666. X    twscopy( &t, dtwstime( ) );
  1667. X    }
  1668. X    else if ( argc - argi == 1 || argc - argi == 2 || argc - argi == 3 )
  1669. X    {
  1670. X    /* One, two, or three args - use them. */
  1671. X    strcpy( buf, argv[argi] );
  1672. X    if ( argc - argi > 1 )
  1673. X        {
  1674. X        strcat( buf, " " );
  1675. X        strcat( buf, argv[argi + 1] );
  1676. X        if ( argc - argi > 2 )
  1677. X        {
  1678. X        strcat( buf, " " );
  1679. X        strcat( buf, argv[argi + 2] );
  1680. X        }
  1681. X        }
  1682. X    twp = dparsetime( buf );
  1683. X    if ( twp == NULL || twp -> tw_flags & TW_JUNK )
  1684. X        {
  1685. X        fprintf( stderr, "illegal date/time: %s\n", buf );
  1686. X        exit( 1 );
  1687. X        }
  1688. X    twscopy( &t, twp );
  1689. X    }
  1690. X    else
  1691. X    {
  1692. X    /* Too many args! */
  1693. X    fprintf( stderr, usage, argv[0] );
  1694. X    exit( 1 );
  1695. X    }
  1696. X
  1697. X    /* Pseudo-randomly decide what the moon is made of, and print it. */
  1698. X    if ( twclock( dtwstime( ) ) % 17 == 3 )
  1699. X    putmoon( &t, numlines, "GREENCHEESE" );
  1700. X    else
  1701. X    putmoon( &t, numlines, "@" );
  1702. X
  1703. X    /* All done. */
  1704. X    exit( 0 );
  1705. X    }
  1706. X
  1707. X
  1708. Xputmoon( t, numlines, atfiller )
  1709. Xstruct tws *t;
  1710. Xint numlines;
  1711. Xchar *atfiller;
  1712. X    {
  1713. X    struct tws twsanewmoon;
  1714. X    long secsynodic = 29*SECSPERDAY + 12*SECSPERHOUR + 44*SECSPERMINUTE + 3;
  1715. X    long secdiff, secphase;
  1716. X    int atflrlen, atflridx, lin, col, midlin, qlitidx;
  1717. X    float angphase, mcap, yrad, xrad, y, xright, xleft;
  1718. X    int colright, colleft, i;
  1719. X    char c;
  1720. X
  1721. X    static char background18[18][37] = {
  1722. X    "             .----------.            ",
  1723. X    "         .--'   o    .   `--.        ",
  1724. X    "       .'@  @@@@@@ O   .   . `.      ",
  1725. X    "     .'@@  @@@@@@@@   @@@@   . `.    ",
  1726. X    "   .'    . @@@@@@@@  @@@@@@    . `.  ",
  1727. X    "  / @@ o    @@@@@@.   @@@@    O   @\\ ",
  1728. X    "  |@@@@               @@@@@@     @@| ",
  1729. X    " / @@@@@   `.-.    . @@@@@@@@  .  @@\\",
  1730. X    " | @@@@   --`-'  .  o  @@@@@@@      |",
  1731. X    " |@ @@                 @@@@@@ @@@   |",
  1732. X    " \\      @@    @   . ()  @@   @@@@@  /",
  1733. X    "  |   @      @@@         @@@  @@@  | ",
  1734. X    "  \\  .   @@  @\\  .      .  @@    o / ",
  1735. X    "   `.   @@@@  _\\ /     .      o  .'  ",
  1736. X    "     `.  @@    ()---           .'    ",
  1737. X    "       `.     / |  .    o    .'      ",
  1738. X    "         `--./   .       .--'        ",
  1739. X    "             `----------'            "};
  1740. X
  1741. X    static char background19[19][39] = {
  1742. X    "              .----------.             ",
  1743. X    "          .--'   o    .   `--.         ",
  1744. X    "       .-'@  @@@@@@ O   .   . `-.      ",
  1745. X    "     .' @@  @@@@@@@@   @@@@   .  `.    ",
  1746. X    "    /     . @@@@@@@@  @@@@@@     . \\   ",
  1747. X    "   /@@  o    @@@@@@.   @@@@    O   @\\  ",
  1748. X    "  /@@@@                @@@@@@     @@@\\ ",
  1749. X    " . @@@@@   `.-./    . @@@@@@@@  .  @@ .",
  1750. X    " | @@@@   --`-'  .      @@@@@@@       |",
  1751. X    " |@ @@        `      o  @@@@@@ @@@@   |",
  1752. X    " |      @@        o      @@   @@@@@@  |",
  1753. X    " ` .  @       @@     ()   @@@  @@@@   '",
  1754. X    "  \\     @@   @@@@        . @@   .  o / ",
  1755. X    "   \\   @@@@  @@\\  .           o     /  ",
  1756. X    "    \\ . @@     _\\ /    .      .-.  /   ",
  1757. X    "     `.    .    ()---        `-' .'    ",
  1758. X    "       `-.    ./ |  .   o     .-'      ",
  1759. X    "          `--./   .       .--'         ",
  1760. X    "              `----------'             "};
  1761. X
  1762. X    static char background23[23][47] = {
  1763. X    "                 .------------.                ",
  1764. X    "             .--'  o     . .   `--.            ",
  1765. X    "          .-'   .    O   .       . `-.         ",
  1766. X    "       .-'@   @@@@@@@   .  @@@@@      `-.      ",
  1767. X    "      /@@@  @@@@@@@@@@@   @@@@@@@   .    \\     ",
  1768. X    "    ./    o @@@@@@@@@@@   @@@@@@@       . \\.   ",
  1769. X    "   /@@  o   @@@@@@@@@@@.   @@@@@@@   O      \\  ",
  1770. X    "  /@@@@   .   @@@@@@@o    @@@@@@@@@@     @@@ \\ ",
  1771. X    "  |@@@@@               . @@@@@@@@@@@@@ o @@@@| ",
  1772. X    " /@@@@@  O  `.-./  .      @@@@@@@@@@@@    @@  \\",
  1773. X    " | @@@@    --`-'       o     @@@@@@@@ @@@@    |",
  1774. X    " |@ @@@        `    o      .  @@   . @@@@@@@  |",
  1775. X    " |       @@  @         .-.     @@@   @@@@@@@  |",
  1776. X    " \\  . @        @@@     `-'   . @@@@   @@@@  o /",
  1777. X    "  |      @@   @@@@@ .           @@   .       | ",
  1778. X    "  \\     @@@@  @\\@@    /  .  O    .     o   . / ",
  1779. X    "   \\  o  @@     \\ \\  /         .    .       /  ",
  1780. X    "    `\\     .    .\\.-.___   .      .   .-. /'   ",
  1781. X    "      \\           `-'                `-' /     ",
  1782. X    "       `-.   o   / |     o    O   .   .-'      ",
  1783. X    "          `-.   /     .       .    .-'         ",
  1784. X    "             `--.       .      .--'            ",
  1785. X    "                 `------------'                "};
  1786. X    
  1787. X    static char background24[24][49] = {
  1788. X    "                  .------------.                 ",
  1789. X    "             .---' o     .  .   `---.            ",
  1790. X    "          .-'   .    O    .       .  `-.         ",
  1791. X    "        .'@   @@@@@@@   .   @@@@@       `.       ",
  1792. X    "      .'@@  @@@@@@@@@@@    @@@@@@@   .    `.     ",
  1793. X    "     /    o @@@@@@@@@@@    @@@@@@@       .  \\    ",
  1794. X    "    /@  o   @@@@@@@@@@@.    @@@@@@@   O      \\   ",
  1795. X    "   /@@@   .   @@@@@@@o     @@@@@@@@@@     @@@ \\  ",
  1796. X    "  /@@@@@               .  @@@@@@@@@@@@@ o @@@@ \\ ",
  1797. X    "  |@@@@  O  `.-./  .       @@@@@@@@@@@@    @@  | ",
  1798. X    " / @@@@    --`-'       o      @@@@@@@@ @@@@     \\",
  1799. X    " |@ @@@     @  `           .   @@     @@@@@@@   |",
  1800. X    " |      @           o          @      @@@@@@@   |",
  1801. X    " \\       @@            .-.      @@@    @@@@  o  /",
  1802. X    "  | . @        @@@     `-'    . @@@@           | ",
  1803. X    "  \\      @@   @@@@@ .            @@   .        / ",
  1804. X    "   \\    @@@@  @\\@@    /  .   O    .     o   . /  ",
  1805. X    "    \\ o  @@     \\ \\  /          .    .       /   ",
  1806. X    "     \\     .    .\\.-.___    .      .   .-.  /    ",
  1807. X    "      `.          `-'                 `-' .'     ",
  1808. X    "        `.   o   / |      o    O   .    .'       ",
  1809. X    "          `-.   /      .       .     .-'         ",
  1810. X    "             `---.       .      .---'            ",
  1811. X    "                  `------------'                 "};
  1812. X    static char background29[29][59] = {
  1813. X    "                      .--------------.                     ",
  1814. X    "                 .---'  o        .    `---.                ",
  1815. X    "              .-'    .    O  .         .   `-.             ",
  1816. X    "           .-'     @@@@@@       .             `-.          ",
  1817. X    "         .'@@   @@@@@@@@@@@       @@@@@@@   .    `.        ",
  1818. X    "       .'@@@  @@@@@@@@@@@@@@     @@@@@@@@@         `.      ",
  1819. X    "      /@@@  o @@@@@@@@@@@@@@     @@@@@@@@@     O     \\     ",
  1820. X    "     /        @@@@@@@@@@@@@@  @   @@@@@@@@@ @@     .  \\    ",
  1821. X    "    /@  o      @@@@@@@@@@@   .  @@  @@@@@@@@@@@     @@ \\   ",
  1822. X    "   /@@@      .   @@@@@@ o       @  @@@@@@@@@@@@@ o @@@@ \\  ",
  1823. X    "  /@@@@@                  @ .      @@@@@@@@@@@@@@  @@@@@ \\ ",
  1824. X    "  |@@@@@    O    `.-./  .        .  @@@@@@@@@@@@@   @@@  | ",
  1825. X    " / @@@@@        --`-'       o        @@@@@@@@@@@ @@@    . \\",
  1826. X    " |@ @@@@ .  @  @    `    @            @@      . @@@@@@    |",
  1827. X    " |   @@                         o    @@   .     @@@@@@    |",
  1828. X    " |  .     @   @ @       o              @@   o   @@@@@@.   |",
  1829. X    " \\     @    @       @       .-.       @@@@       @@@      /",
  1830. X    "  |  @    @  @              `-'     . @@@@     .    .    | ",
  1831. X    "  \\ .  o       @  @@@@  .              @@  .           . / ",
  1832. X    "   \\      @@@    @@@@@@       .                   o     /  ",
  1833. X    "    \\    @@@@@   @@\\@@    /        O          .        /   ",
  1834. X    "     \\ o  @@@       \\ \\  /  __        .   .     .--.  /    ",
  1835. X    "      \\      .     . \\.-.---                   `--'  /     ",
  1836. X    "       `.             `-'      .                   .'      ",
  1837. X    "         `.    o     / | `           O     .     .'        ",
  1838. X    "           `-.      /  |        o             .-'          ",
  1839. X    "              `-.          .         .     .-'             ",
  1840. X    "                 `---.        .       .---'                ",
  1841. X    "                      `--------------'                     "};
  1842. X
  1843. X    static char qlits[8][16] = {
  1844. X    "New Moon +     ",
  1845. X    "First Quarter +",
  1846. X    "Full Moon +    ",
  1847. X    "Last Quarter + ",
  1848. X    "First Quarter -",
  1849. X    "Full Moon -    ",
  1850. X    "Last Quarter - ",
  1851. X    "New Moon -     " };
  1852. X
  1853. X
  1854. X    /* Find the length of the atfiller string. */
  1855. X    atflrlen = strlen( atfiller );
  1856. X
  1857. X    /* Convert a new moon date from a string to a tws. */
  1858. X    twscopy( &twsanewmoon, dparsetime( "05jan81 23:24:00 PST" ) );
  1859. X
  1860. X    /* Subtract the new moon date from the desired date to get the interval
  1861. X       since the new moon. */
  1862. X    secdiff = twsubtract( t, &twsanewmoon );
  1863. X
  1864. X    /* Figure out the phase - the interval since the last new moon. */
  1865. X    secphase = secdiff % secsynodic;
  1866. X    if ( secphase < 0L )
  1867. X    secphase += secsynodic;  /* fucking mathematician language designers */
  1868. X    angphase = (float) secphase / (float) secsynodic * 2.0 * PI;
  1869. X    mcap = -cos( angphase );
  1870. X
  1871. X    /* Figure out how big the moon is. */
  1872. X    yrad = numlines / 2.0;
  1873. X    xrad = yrad / ASPECTRATIO;
  1874. X
  1875. X    /* Figure out some other random stuff. */
  1876. X    midlin = numlines / 2;
  1877. X    qlitidx = angphase / PI * 2.0;
  1878. X
  1879. X    /* Now output the moon, a slice at a time. */
  1880. X    atflridx = 0;
  1881. X    for ( lin = 0; lin < numlines; lin = lin + 1 )
  1882. X    {
  1883. X    /* Compute the edges of this slice. */
  1884. X    y = lin + 0.5 - yrad;
  1885. X    xright = xrad * sqrt( 1.0 - ( y * y ) / ( yrad * yrad ) );
  1886. X    xleft = -xright;
  1887. X    if ( angphase >= 0.0 && angphase < PI )
  1888. X        xleft = mcap * xleft;
  1889. X    else
  1890. X        xright = mcap * xright;
  1891. X    colleft = (int) (xrad + 0.5) + (int) (xleft + 0.5);
  1892. X    colright = (int) (xrad + 0.5) + (int) (xright + 0.5);
  1893. X
  1894. X    /* Now output the slice. */
  1895. X    for ( i = 0; i < colleft; i++ )
  1896. X        putchar( ' ' );
  1897. X    for ( col = colleft; col <= colright; col = col + 1 )
  1898. X        {
  1899. X        switch ( numlines )
  1900. X        {
  1901. X        case 18:
  1902. X            c = background18[lin][col];
  1903. X            break;
  1904. X        case 19:
  1905. X            c = background19[lin][col];
  1906. X            break;
  1907. X            case 23:
  1908. X            c = background23[lin][col];
  1909. X            break;
  1910. X            case 24:
  1911. X            c = background24[lin][col];
  1912. X            break;
  1913. X            case 29:
  1914. X            c = background29[lin][col];
  1915. X            break;
  1916. X        default:
  1917. X            c = '@';
  1918. X        }
  1919. X        if ( c != '@' )
  1920. X        putchar( c );
  1921. X        else
  1922. X        {
  1923. X        putchar( atfiller[atflridx] );
  1924. X        atflridx = ( atflridx + 1 ) % atflrlen;
  1925. X        }
  1926. X        }
  1927. X
  1928. X    /* Output the end-of-line information, if any. */
  1929. X    if ( lin == midlin - 2 )
  1930. X        {
  1931. X        putchar( '\t' );
  1932. X        putchar( '\t' );
  1933. X        fputs( qlits[qlitidx], stdout );
  1934. X        }
  1935. X    else if ( lin == midlin - 1)
  1936. X        {
  1937. X        putchar( '\t' );
  1938. X        putchar( '\t' );
  1939. X        putseconds( secphase % (secsynodic / 4) );
  1940. X        }
  1941. X    else if ( lin == midlin )
  1942. X        {
  1943. X        putchar( '\t' );
  1944. X        putchar( '\t' );
  1945. X        fputs( qlits[qlitidx + 4], stdout );
  1946. X        }
  1947. X    else if ( lin == midlin + 1 )
  1948. X        {
  1949. X        putchar( '\t' );
  1950. X        putchar( '\t' );
  1951. X        putseconds( (secsynodic - secphase) % (secsynodic / 4) );
  1952. X        }
  1953. X
  1954. X    putchar( '\n' );
  1955. X    }
  1956. X
  1957. X    }
  1958. X
  1959. X
  1960. Xputseconds( secs )
  1961. Xlong secs;
  1962. X    {
  1963. X    long days, hours, minutes;
  1964. X
  1965. X    days = secs / SECSPERDAY;
  1966. X    secs = secs - days * SECSPERDAY;
  1967. X    hours = secs / SECSPERHOUR;
  1968. X    secs = secs - hours * SECSPERHOUR;
  1969. X    minutes = secs / SECSPERMINUTE;
  1970. X    secs = secs - minutes * SECSPERMINUTE;
  1971. X
  1972. X    printf( "%ld %2ld:%02ld:%02ld", days, hours, minutes, secs );
  1973. X    }
  1974. SHAR_EOF
  1975. if test 12899 -ne "`wc -c < 'phoon.c'`"
  1976. then
  1977.     echo shar: error transmitting "'phoon.c'" '(should have been 12899 characters)'
  1978. fi
  1979. fi # end of overwriting check
  1980. echo shar: extracting "'phoon.man'" '(696 characters)'
  1981. if test -f 'phoon.man'
  1982. then
  1983.     echo shar: will not over-write existing file "'phoon.man'"
  1984. else
  1985. sed 's/^X//' << \SHAR_EOF > 'phoon.man'
  1986. X.TH phoon 1 "08 November 1986"
  1987. X.SH NAME
  1988. Xphoon \- show the PHase of the mOON
  1989. X.SH SYNOPSIS
  1990. X.in +.5i
  1991. X.ti -.5i
  1992. Xphoon  \%[ -l <lines> ]  \%[ <date> ]
  1993. X.in -.5i
  1994. X.SH DESCRIPTION
  1995. X.I Phoon
  1996. Xdisplays the phase of the moon, either currently
  1997. Xor at a specified date / time.
  1998. XUnlike other such programs, which just tell you how long since first quarter
  1999. Xor something like that, phoon
  2000. X.I shows
  2001. Xyou the phase with a cute little picture.
  2002. XYou can vary the size of the picture with the -l flag, but only some
  2003. Xsizes have pictures defined - other sizes use @'s.
  2004. X.SH "SEE\ ALSO"
  2005. X.IR deltime(1),
  2006. X.IR libtws(3)
  2007. X.SH AUTHOR
  2008. XJef Poskanzer
  2009. X.SH BUGS
  2010. XThe algorithm for determining the phase is very simple, but not very
  2011. Xaccurate.
  2012. SHAR_EOF
  2013. if test 696 -ne "`wc -c < 'phoon.man'`"
  2014. then
  2015.     echo shar: error transmitting "'phoon.man'" '(should have been 696 characters)'
  2016. fi
  2017. fi # end of overwriting check
  2018. echo shar: extracting "'tws.h'" '(2290 characters)'
  2019. if test -f 'tws.h'
  2020. then
  2021.     echo shar: will not over-write existing file "'tws.h'"
  2022. else
  2023. sed 's/^X//' << \SHAR_EOF > 'tws.h'
  2024. X/* tws.h - header file for libtws date/time library */
  2025. X
  2026. X
  2027. X/* Definition of the tws data structure. */
  2028. X
  2029. Xstruct tws {
  2030. X    int     tw_sec;
  2031. X    int     tw_min;
  2032. X    int     tw_hour;
  2033. X
  2034. X    int     tw_mday;
  2035. X    int     tw_mon;
  2036. X    int     tw_year;
  2037. X
  2038. X    int     tw_wday;
  2039. X    int     tw_yday;
  2040. X
  2041. X    int     tw_zone;
  2042. X
  2043. X    long    tw_clock;
  2044. X
  2045. X    int     tw_flags;
  2046. X#define TW_NULL 0x0000
  2047. X#define TW_SDAY 0x0007        /* how day-of-week was determined */
  2048. X#define   TW_SNIL 0x0000    /*   not given */
  2049. X#define   TW_SEXP 0x0001    /*   explicitly given */
  2050. X#define   TW_SIMP 0x0002    /*   implicitly given */
  2051. X#define TW_DST  0x0010        /* daylight savings time */
  2052. X#define TW_ZONE 0x0020        /* use numeric timezones only */
  2053. X#define TW_JUNK 0x0040        /* date string contained junk */
  2054. X};
  2055. X
  2056. X
  2057. X/* Declarations of routines. */
  2058. X
  2059. Xvoid twscopy( );
  2060. X    /* twscopy( &totws, &fromtws ) copies a tws */
  2061. Xint twsort( );
  2062. X    /* twsort( &tws1, &tws2 ) compares two tws's: 1 means tws1 is
  2063. X       later; -1 means tws1 is earlier; 0 means they are equal */
  2064. Xlong twclock( );
  2065. X    /* twclock( &tws ) turns a tws into a time(3)-style clock value */
  2066. Xlong twjuliandate( );
  2067. X    /* twjuliandate( &tws ) returns the Julian day number of a tws */
  2068. Xlong twsubtract( );
  2069. X    /* twsubtract( &tws1, &tws2 ) returns seconds of difference */
  2070. X
  2071. X/* These routines are functionally similar to the ctime(3) routines
  2072. X   in the standard Unix library. */
  2073. Xchar *dctime( );
  2074. X    /* dctime( &tws ) returns a string for the date/time passed in */
  2075. Xstruct tws *dlocaltime( );
  2076. X    /* dlocaltime( &clock ) turns a time(3) clock value into a tws */
  2077. Xstruct tws *dgmtime( );
  2078. X    /* dgmtime( &clock ) turns a time(3) clock value into a tws */
  2079. Xchar *dasctime( );
  2080. X    /* dasctime( &tws, flags ) turns a tws into a string */
  2081. Xchar *dtimezone( );
  2082. X    /* dtimezone( offset, flags ) returns the name of the time zone */
  2083. X
  2084. Xchar *dtimenow( );
  2085. X    /* dtimenow( ) returns a string for the current date/time */
  2086. X
  2087. Xstruct tws *dparsetime( );
  2088. X    /* dparsetime( &str ) turns a string into a tws */
  2089. X
  2090. Xstruct tws *dtwstime( );
  2091. X    /* dtwstime( ) returns a tws for the current date/time */
  2092. X
  2093. X#ifdef ATZ
  2094. X#define dtime(cl) dasctime( dlocaltime( cl ), TW_NULL )
  2095. X#else ATZ
  2096. X#define dtime(cl) dasctime( dlocaltime( cl ), TW_ZONE )
  2097. X#endif ATZ
  2098. X
  2099. X#define dtwszone(tw) dtimezone( tw -> tw_zone, tw -> tw_flags )
  2100. X
  2101. X
  2102. Xextern char   *tw_dotw[], *tw_ldotw[], *tw_moty[];
  2103. SHAR_EOF
  2104. if test 2290 -ne "`wc -c < 'tws.h'`"
  2105. then
  2106.     echo shar: error transmitting "'tws.h'" '(should have been 2290 characters)'
  2107. fi
  2108. fi # end of overwriting check
  2109. #    End of shell archive
  2110. exit 0
  2111.  
  2112.